import json
from django.http import JsonResponse, HttpResponse
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from assess.models import *
from assess.engine import JudgeEngine
from login.models import *
import os
from datetime import datetime
import glob
static_file_path = 'static/files/'


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def class_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    point = json_dict.get('point', None)
    if key is not None and point is not None:
        point = float(point)
        key = int(key)
        users = MyUser.objects.filter(id=key)
        s = ClassPoint.objects.filter(user=users[0])
        if len(s) == 0:
            p = ClassPoint.objects.create(user=users[0], point=point)
        else:
            p = s[0]
            p.point = point
        p.save()
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_class_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    if key is not None:
        key = int(key)
        users = MyUser.objects.filter(id=key)
        s = ClassPoint.objects.filter(user=users[0])
        if len(s) == 0:
            point = -1
        else:
            point = s[0].point
        data = dict()
        data['point'] = point
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
                'data': data
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def absence_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    point = json_dict.get('point', None)
    if key is not None and point is not None:
        point = float(point)
        key = int(key)
        users = MyUser.objects.filter(id=key)
        s = AbsencePoint.objects.filter(user=users[0])
        if len(s) == 0:
            p = AbsencePoint.objects.create(user=users[0], point=point)
        else:
            p = s[0]
            p.point = point
        p.save()
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_absence_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    if key is not None:
        key = int(key)
        users = MyUser.objects.filter(id=key)
        s = AbsencePoint.objects.filter(user=users[0])
        if len(s) == 0:
            point = -1
        else:
            point = s[0].point
        data = dict()
        data['point'] = point
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
                'data': data
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def paper_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    point = json_dict.get('point', None)
    if key is not None and point is not None:
        point = float(point)
        key = int(key)
        users = MyUser.objects.filter(id=key)
        s = PaperPoint.objects.filter(user=users[0])
        if len(s) == 0:
            p = PaperPoint.objects.create(user=users[0], point=point)
        else:
            p = s[0]
            p.point = point
        p.save()
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_paper_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    if key is not None:
        key = int(key)
        users = MyUser.objects.filter(id=key)
        s = PaperPoint.objects.filter(user=users[0])
        if len(s) == 0:
            point = -1
        else:
            point = s[0].point
        data = dict()
        data['point'] = point
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
                'data': data
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def new_work(request):
    try:
        key = request.POST.get("key")
        name = request.POST.get("name")
        description = request.POST.get("description")
        input_files = request.FILES.getlist("input_file")
        output_files = request.FILES.getlist("output_file")
        # files = request.FILES.getlist("output_file")
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = int(key)
    chapters = Chapter.objects.filter(id=key)
    if len(input_files) != 1 or len(output_files) != 1:
        return JsonResponse({'code': 500, 'message': '文件数量不符'})
    url = static_file_path + 'homework_data/' + datetime.strftime(datetime.now(), '%Y%m%d%H%M%S') + '.in'
    d = open(url, 'wb+')
    for chunk in input_files[0].chunks():
        d.write(chunk)
    d.close()
    url2 = static_file_path + 'homework_data/' + datetime.strftime(datetime.now(), '%Y%m%d%H%M%S') + '.out'
    d = open(url2, 'wb+')
    for chunk in output_files[0].chunks():
        d.write(chunk)
    d.close()
    p = Homework.objects.create(name=name, description=description,
                                chapter=chapters[0], input_file=url, output_file=url2)
    p.save()
    return JsonResponse({'code': 200, 'message': '请求成功'})


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def modify_work(request):
    input_files = None
    output_files = None
    try:
        work_key = request.POST.get("work_key")
        key = request.POST.get("key")
        name = request.POST.get("name")
        description = request.POST.get("description")
        input_files = request.FILES.getlist("input_file")
        output_files = request.FILES.getlist("output_file")
        # files = request.FILES.getlist("output_file")
    except Exception:
        pass
        # return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = int(key)
    chapters = Chapter.objects.filter(id=key)
    # if len(input_files) != 1 or len(output_files) != 1:
    #     return JsonResponse({'code': 500, 'message': '文件数量不符'})
    work_key = int(work_key)
    p = Homework.objects.filter(id=work_key)[0]
    if input_files is not None and len(input_files) > 0:
        url = static_file_path + 'homework_data/' + datetime.strftime(datetime.now(), '%Y%m%d%H%M%S') + '.in'
        d = open(url, 'wb+')
        for chunk in input_files[0].chunks():
            d.write(chunk)
        d.close()
        p.input_file = url
    if output_files is not None and len(output_files) > 0:
        url2 = static_file_path + 'homework_data/' + datetime.strftime(datetime.now(), '%Y%m%d%H%M%S') + '.out'
        d = open(url2, 'wb+')
        for chunk in output_files[0].chunks():
            d.write(chunk)
        d.close()
        p.output_file = url2
    p.name = name
    p.description = description
    p.chapter = chapters[0]
    p.save()
    return JsonResponse({'code': 200, 'message': '请求成功'})


@api_view(['POST'])
@permission_classes((IsAuthenticated, ))
@authentication_classes((JSONWebTokenAuthentication,))
def query_work_list(request):
    homeworks = Homework.objects.filter()
    data = list()
    for homework in homeworks:
        p = dict()
        p['name'] = homework.name
        p['key'] = homework.id
        p['input_file'] = homework.input_file
        p['output_file'] = homework.output_file
        p['chapter_key'] = homework.chapter.id
        p['description'] = homework.description
        data.append(p)
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data,
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, ))
@authentication_classes((JSONWebTokenAuthentication,))
def submit(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    work_key = json_dict.get('work_key', None)
    code = json_dict.get('code', None)
    code_type = json_dict.get('code_type', None)
    if key is not None and work_key is not None and code is not None and code_type is not None:
        user = MyUser.objects.get(id=int(key))
        homework = Homework.objects.get(id=int(work_key))
        sb = HomeworkSubmit.objects.filter(user=user, work=homework)
        if len(sb) == 0:
            p = HomeworkSubmit.objects.create(user=user, work=homework, code=code, code_type=int(code_type))
        else:
            p = sb[0]
            p.code = code
            p.code_type = code_type
            p.point = -1
        eng = JudgeEngine()
        status_dic = eng.judge(code_type=code_type, code=code, homework=homework)
        p.status = status_dic['status']
        p.info = status_dic['info']
        p.run_time = status_dic.get('run_time', '')
        p.code_output = status_dic.get('code_output', '')
        p.length = status_dic.get('length', '')
        p.save()
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
                'data': status_dic,
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_work_teacher(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    work_key = json_dict.get('work_key', None)
    if key is not None and work_key is not None:
        user = MyUser.objects.get(id=int(key))
        homework = Homework.objects.get(id=int(work_key))
        submits = HomeworkSubmit.objects.filter(user=user, work=homework)
        data = dict()
        if len(submits) > 0:
            data['code'] = submits[0].code
            data['status'] = submits[0].status
            data['code_type'] = submits[0].code_type
            data['key'] = submits[0].id
            data['info'] = submits[0].info
            data['run_time'] = submits[0].run_time
            data['code_output'] = submits[0].code_output
            data['length'] = submits[0].length
            data['point'] = submits[0].point
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
                'data': data,
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def work_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    point = json_dict.get('point', None)
    if key is not None and point is not None:
        homework_submit = HomeworkSubmit.objects.get(id=int(key))
        homework_submit.point = point
        homework_submit.save()
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_work_point(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'loads request body error'})
    key = json_dict.get('key', None)
    if key is not None:
        user = MyUser.objects.get(id=int(key))
        homeworks = HomeworkSubmit.objects.filter(user=user)
        data = list()
        for homework in homeworks:
            p = dict()
            p['status'] = homework.status
            p['code_type'] = homework.code_type
            p['key'] = homework.id
            p['point'] = homework.point
            p['info'] = homework.info
            p['run_time'] = homework.run_time
            p['code_output'] = homework.code_output
            p['length'] = homework.length
            p['homework_key'] = homework.work.id
            p['UpdatedAt'] = homework.UpdatedAt
            data.append(p)
        return JsonResponse(
            {
                'code': 200,
                'message': '请求成功',
                'data': data
            }
        )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': 'parse param error'
            }
        )
